/*
** File name:		window_aging_test.c
** Brief: 
** COPYRIGHT(C) gkt 2019 
** ------------------------------------------------------- 
** Module Information: 
** 
** Revision History -------------------------------------- 
** ------------------------------------------------------- 
**	Date 		Version		Action				Author   
** ------------------------------------------------------- 
**	2019-11-7 	1.0			Created				liwenjie   
** 
*/ 

/* Includes -----------------------------------------------------*/
#include "gkt_types.h"
#include "gkt_debug.h"
#include "gkt_system.h"
#include "window_common.h"
#include "window_opcode.h"
#include "string.h"
#include "gkt_key.h"
#include "gkt_driver.h"
#include "gkt_fpsensor.h"
#include "gkt_rfid.h"
#include "gkt_door.h"

/* Global Variables ---------------------------------------------*/
/* Macro --------------------------------------------------------*/
#define	AGING_TEST_FAIL_CNT_MAX	1

enum {
	WINDOW_AGING_TEST_PRE_DOING = 0,
	WINDOW_AGING_TEST_DOING,
	WINDOW_AGING_TEST_MAX
};

enum {
	WIDGET_ID_LIST = 0,
	WIDGET_ID_MAX
};

static const gkt_widget_list_attr_s sc_window_aging_test_list_attr = 
	GKT_WIDGET_LIST_STATIC_ATTR(0, NULL);

GKT_WINDOW_WIDGET_DESCS_DEFINE(aging_test) = {
	[WIDGET_ID_LIST] = GKT_WIDGET_LIST_DESC(
										0, 
										&sc_window_aging_test_list_attr),					
};

#ifdef GKT_CONFIG_WINDOW_AGING_TEST_SAVE_PER_TIMES
#define WINDOW_AGING_TEST_SAVE_PER_TIMES	GKT_CONFIG_WINDOW_AGING_TEST_SAVE_PER_TIMES
#else
#define WINDOW_AGING_TEST_SAVE_PER_TIMES	10
#endif

typedef struct _window_aging_test {
	uint32_t	flags;

	int	id;

	int	current_times;
	int	total_times;
	int	fail_times;
	int	save_per_times;
	
	int card_trigger;	
} window_aging_test_s;
static window_aging_test_s s_aging_test;

#define WINDOW_AGING_TEST_KEY_LED_FLICKER_TIMES	2
#define WINDOW_AGING_TEST_KEY_LED_FLICKER_HALF_CYCLE	200
static int window_aging_test(uint32_t error_bits[WINDOW_SELF_INSPECT_MAX])
{	
	uint32_t cnt = 2, lock_status;
	int failed_nums;

	//LED TEST
	cnt = WINDOW_AGING_TEST_KEY_LED_FLICKER_TIMES;
	while(cnt--) {
		/* all off */
		gkt_key_led_control(GKT_KEY_LED_CTRL_BRIGHT, 0);
		gkt_delay_ms(WINDOW_AGING_TEST_KEY_LED_FLICKER_HALF_CYCLE);

		/* all on */
		gkt_key_led_control(GKT_KEY_LED_CTRL_BRIGHT, ~0);
		gkt_delay_ms(WINDOW_AGING_TEST_KEY_LED_FLICKER_HALF_CYCLE);
	}

	//PERIPHERALS TEST
	failed_nums = window_common_self_inspect(error_bits);

	//MOTOR TEST
	lock_status = gkt_door_lock_get_status();
	if(lock_status != GKT_DOOR_LOCK_ST_CLOSED)
		gkt_door_lock_close(0);
	else
		gkt_door_lock_open();

#if defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) && GKT_CONFIG_DOOR_LOCK_AUTOMATIC
	gkt_delay_ms(GKT_DOOR_LOCK_MOTOR_FULL_ROTATE_TIME_MS);//Wait for the motor to rotate in place
#endif

	return failed_nums;
}

static void window_aging_test_failed(uint32_t results[WINDOW_SELF_INSPECT_MAX])
{
	gkt_voice_output_playback_attr_s play_params;
	uint32_t voice_id=WINDOW_VOICE_COMBINED_ID(alarm);
	uint32_t failed_module_bits, i;

	failed_module_bits = 0;
	for (i = 0; i < WINDOW_SELF_INSPECT_MAX; i++) {
		if (results[i] != 0)
			failed_module_bits |= 1U << (i+1);
	}

	switch(failed_module_bits) {
		case 0x2:
			voice_id = gc_window_factory_inspect_error_voice_ids[5];
			break;
		case 0x4:
			voice_id = gc_window_factory_inspect_error_voice_ids[3];
			break;
		case 0x8:
			voice_id = gc_window_factory_inspect_error_voice_ids[4];
			break;
		default:
			break;
	}
	
	play_params.interval = 1000;
	play_params.times = ~0;
	gkt_window_voice_play(NULL, voice_id, 0, &play_params);	
}

#define WINDOW_AGING_TEST_INTERVAL	5000
static void window_aging_test_do(void)
{
	uint32_t self_inspect_error_bits[WINDOW_SELF_INSPECT_MAX];
	int self_inspect_failed_nums;

	window_common_mask_all();

	gp_window_unreset_data->aging_test_cnt = s_aging_test.total_times;

	self_inspect_failed_nums = window_aging_test(self_inspect_error_bits);

	//VOICE TEST
	if(!self_inspect_failed_nums) {
		s_aging_test.current_times++;
		s_aging_test.total_times++;
		s_aging_test.save_per_times--;
		if (!s_aging_test.save_per_times) {
			s_aging_test.save_per_times = WINDOW_AGING_TEST_SAVE_PER_TIMES;
			window_data_save();
		}
		
		gkt_window_timer_set(WINDOW_AGING_TEST_DOING, 
						WINDOW_AGING_TEST_INTERVAL, 0, 0);
	}
	else {
		window_data_save();

		s_aging_test.fail_times++;
		if (s_aging_test.fail_times >= AGING_TEST_FAIL_CNT_MAX) {
			window_aging_test_failed(self_inspect_error_bits);
		}
		else {
			gkt_window_timer_set(WINDOW_AGING_TEST_DOING, 
								WINDOW_AGING_TEST_INTERVAL, 0, 0);
		}
	}

	window_common_mask_except_cancel_ok();
}

/* Static Functions ---------------------------------------------*/
static int window_aging_test_event_handler(
					uint32_t major_type, uint32_t minor_type, 
					uint32_t widget_id, uint32_t data)
{
	switch (major_type) {
		case GKT_EVENT_WINDOW:
			if (GKT_WINDOW_INIT == minor_type) {
				gkt_window_system_standby_disable();
				gkt_window_timeout_disable("aging_test_event - INIT");
				gkt_keypad_control(GKT_KEYPAD_CTRL_REAL_TRIM, GKT_KEYPAD_REAL_TRIM_DISABLE);

				s_aging_test.id = WINDOW_AGING_TEST_MAX;
				s_aging_test.current_times = 0;
				s_aging_test.total_times = gp_window_unreset_data->aging_test_cnt;
				s_aging_test.fail_times = 0;
				s_aging_test.save_per_times = WINDOW_AGING_TEST_SAVE_PER_TIMES;
				s_aging_test.flags = data;
			}
			else if (GKT_WINDOW_ACTIVE == minor_type) {
				window_common_mask_except_cancel_ok();

				gkt_window_system_door_set_always_open_state(1);
				gkt_window_timer_set(WINDOW_AGING_TEST_DOING, 
					2500, 0, 0);
			}
			else if(GKT_WINDOW_UNINIT == minor_type) {
				gkt_window_system_door_set_always_open_state(0);
				gkt_door_lock_close(0);

				gp_window_unreset_data->aging_test_cnt = s_aging_test.total_times;
				window_data_save();

				gkt_keypad_control(GKT_KEYPAD_CTRL_REAL_TRIM, GKT_KEYPAD_REAL_TRIM_ENABLE);
				gkt_window_timeout_enable("aging_test_event - UNIT");
				gkt_window_system_standby_enable();
			}
			break;
		case GKT_EVENT_TIMER:
			gkt_window_timer_clear(WINDOW_AGING_TEST_DOING);
			window_aging_test_do();
			break;
		case GKT_EVENT_KEY:
			if ((GKT_KEY_OK == minor_type) || (GKT_KEY_CANCEL == minor_type)) {
				gkt_window_exit();
				return GKT_EVENT_HANDLE_COMPLETE;
			}	
			break;
#if defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) && GKT_CONFIG_DOOR_LOCK_AUTOMATIC
		case GKT_EVENT_SYSTEM:
			return GKT_EVENT_HANDLE_COMPLETE;
#endif
		default:
			break;
	}

	return GKT_EVENT_HANDLE_CONTINUE;
}

/* Functions ----------------------------------------------------*/
GKT_WINDOW_DESC_DEFINE(aging_test);

/* end */


